package com.hooya.fa.eu.biz.business.service;


import cn.hutool.core.bean.BeanUtil;
import com.hooya.fa.eu.biz.dao.entity.MetaStkCustoms;
import com.hooya.fa.eu.biz.dao.entity.StkOrigDataCollect;
import com.hooya.fa.eu.biz.dao.entity.dto.B2bDataDTO;
import com.hooya.fa.eu.biz.dao.mapper.*;
import com.hooya.fa.eu.biz.service.impl.CommonService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Service
@Slf4j
public class Insert_B2B {

    @Autowired
    private ProForMaMmMapper proForMaMmMapper;

    @Autowired
    private TempMmjlMapper tempMmjlMapper;

    @Autowired
    private CostHisMapper costHisMapper;

    @Autowired
    private CostLastMapper costLastMapper;

    @Autowired
    private MetaStkCustomsMapper metaStkCustomsMapper;

    @Autowired
    private MetaCorpHeaderMapper metaCorpHeaderMapper;

    @Autowired
    private CommonService commonService;
	@Transactional
    public void insert_b2b(String start) {
        try {
			log.info("开始执行B2B数据插入任务");
			// 获取当前日期作为开始日期
            Map<String, String> dateMap = commonService.dateChange(start);
            String currMonthStart = dateMap.get("currMonthStart");
            String nextMonthStart = dateMap.get("nextMonthStart");
            String currMonthEnd = dateMap.get("currMonthEnd");

            // 查询历史价格数据
            List<B2bDataDTO> hisPriceList = costHisMapper.selectPriceData(currMonthStart, nextMonthStart);
            // 查询最新价格数据
            List<B2bDataDTO> lastPriceList = costLastMapper.selectLatestPrice();

            // 获取首次出现日期数据
            List<B2bDataDTO> firstDayData = tempMmjlMapper.selectFirstDayData(currMonthStart, nextMonthStart);

            // 获取主要数据
            List<B2bDataDTO> mainData = getMainData(currMonthStart, nextMonthStart);

            // 添加价格
            List<B2bDataDTO> priceData = addPrice(hisPriceList, lastPriceList, firstDayData);

            //构建海运数据的Map映射集合
            Map<String, List<B2bDataDTO>> oceanFeeDataMap = priceData.stream().collect(Collectors.groupingBy(B2bDataDTO::getCpbh));

            //merge -->  mainData数据和plnPriceData数据
            List<B2bDataDTO> mergeData = new ArrayList<>();
            for (B2bDataDTO mainItem : mainData) {
                String key = mainItem.getCpbh();
                if (oceanFeeDataMap.containsKey(key)) {
                    List<B2bDataDTO> B2bDataDTOS = oceanFeeDataMap.get(key);
                    B2bDataDTOS.forEach(f -> {
                        B2bDataDTO newItem = new B2bDataDTO();
                        BeanUtils.copyProperties(mainItem, newItem);
                        newItem.setPrice(f.getPrice());
                        newItem.setOceanfee(f.getOceanfee());
                        mergeData.add(newItem);
                    });
                } else {
                    mergeData.add(mainItem);
                }
            }

            List<B2bDataDTO> noPriceData = mergeData.stream().filter(f -> f.getPrice() == null).collect(Collectors.toList());
            if(!noPriceData.isEmpty()){
                log.error("异常数据共有条数：{}， 异常数据为：{}", noPriceData.size(), noPriceData);
                //TODO -- 后续取消注释
//                throw new RuntimeException("异常数据共有条数：" + noPriceData.size() + "， 异常数据为：" + noPriceData);
            }

            mergeData.forEach(f->f.setCurrency("EUR"));

            // 添加ID
            List<B2bDataDTO> addIdData = addId(mergeData, currMonthStart);

            // 拆分方向
            List<B2bDataDTO> addDirectionData = addDirection(addIdData);

            // 添加发票日期
            List<B2bDataDTO> addInvoiceDateData = addInvoiceDate(addDirectionData, nextMonthStart);
            //更新索引  --  所谓索引不过是判断一条信息的唯一值罢了
            addInvoiceDateData.forEach(f->f.setIndex(f.getSheetnumber()+"|"+f.getDirection()));

            // 添加出口价格
            Map<String, Object> exportPriceResult = addExportPrice(addInvoiceDateData, currMonthEnd);
            List<B2bDataDTO> withExportPriceData = (List<B2bDataDTO>) exportPriceResult.get("withExportPriceData");
            List<B2bDataDTO> withoutExportPriceData = (List<B2bDataDTO>) exportPriceResult.get("withoutExportPriceData");

            // 添加异常出口价格
            List<B2bDataDTO> abWithExportPriceData = addAbnormalExportPrice(withoutExportPriceData, currMonthEnd);

            // 合并所有出口价格数据
            List<B2bDataDTO> allExportPriceData = new ArrayList<>();
            allExportPriceData.addAll(withExportPriceData);
            allExportPriceData.addAll(abWithExportPriceData);
            //更新索引
            allExportPriceData.forEach(f->f.setIndex(f.getSheetnumber()+"|"+f.getDirection()));

            Map<String, List<B2bDataDTO>> exportPriceMap = allExportPriceData.stream().collect(Collectors.groupingBy(f -> f.getCpbh() + f.getIndex()));

            // 合并最终数据
            List<B2bDataDTO> finalData = new ArrayList<>();
            for (B2bDataDTO mainItem : addInvoiceDateData) {
                String key = mainItem.getCpbh() + mainItem.getIndex();
                leftMergeData(mainItem, exportPriceMap, key, finalData);
            }

            // 处理转运类型的数据
            String formattedDate = LocalDate.parse(start, DateTimeFormatter.ofPattern("yyyy-MM-dd")).format(DateTimeFormatter.ofPattern("yyyyMM"));

            finalData.stream().filter(data -> "转运".equals(data.getType())).forEach(data -> {
                data.setOceanfee(BigDecimal.ZERO);
                data.setExportprice(BigDecimal.ZERO);
                data.setInvoiceno("BTOB-" + formattedDate);
                data.setStax(null);
                data.setBtax(null);
            });

            // 数据验证
            commonService.dataVerificationB2b(finalData);

            // 转换为实体类并保存
            List<StkOrigDataCollect> records = commonService.convertB2bToStkOrigDataCollect(finalData);

            commonService.batchInsert(records);

            log.info("B2B数据处理完成，共处理{}条记录", records.size());

			log.info("B2B数据插入任务完成");
        } catch (Exception e) {
            log.error("处理B2B数据失败", e);
            throw new RuntimeException("处理B2B数据失败", e);
        }
    }

    /**
     * 获取主要数据
     */
    private List<B2bDataDTO> getMainData(String start, String end) {
        // 查询temp_mmjl表数据（包含仓库信息）
        List<B2bDataDTO> tempMmjlList = tempMmjlMapper.selectList(start, end);

        // 添加税号头信息
        addTaxIdHeader(tempMmjlList);

        // 添加形式转的买卖记录
        List<B2bDataDTO> proFormaMm = addProFormaMm(start, end, tempMmjlList);
        addTaxIdHeader(proFormaMm);

        // 合并形式转数据
        tempMmjlList.addAll(proFormaMm);

        // 处理买家逻辑
        tempMmjlList.forEach(data -> {
            String buyer = getBuyer(data.getBuyer(), data.getBuyertaxid());
            data.setBuyer(buyer);
        });

        // 注意：在Java中，seller和fromcompany是同一个字段，buyer和tocompany是同一个字段
        // 所以我们只需要处理sellertaxid->stax和buyertaxid->btax的映射
        for (B2bDataDTO data : tempMmjlList) {
            // 将sellertaxid复制到stax
            data.setStax(data.getSellertaxid());

            // 将buyertaxid复制到btax
            data.setBtax(data.getBuyertaxid());
        }

        log.info("获取主要数据成功，数据条数：{}", tempMmjlList.size());
        return tempMmjlList;
    }

    /**
     * 添加税号头信息
     */
    private void addTaxIdHeader(List<B2bDataDTO> dataList) {
        for (B2bDataDTO data : dataList) {
            // 根据业务逻辑设置税号信息
            if (data.getFromcountry() != null) {
                data.setSellertaxid(data.getFromcountry());
            }

            // 买家税号：收货地除DE，PL，IT，ES外均使用FR
            if (data.getTocountry() != null) {
                if ("DE".equals(data.getTocountry()) || "PL".equals(data.getTocountry()) || "IT".equals(data.getTocountry()) || "ES".equals(data.getTocountry())) {
                    data.setBuyertaxid(data.getTocountry());
                } else {
                    data.setBuyertaxid("FR");
                }
            }

            // 无ES税号的公司，改为FR
            if ("ES".equals(data.getTocountry()) && data.getBuyer() != null) {
                if ("kerui".equals(data.getBuyer()) || "giantex".equals(data.getBuyer())) {
                    data.setBuyertaxid("FR");
                }
            }

            // 特殊公司
            if (data.getBuyer() != null) {
                if ("mingdun".equals(data.getBuyer())) {
                    data.setBuyertaxid("FR");
                } else if ("itsrlcostway".equals(data.getBuyer())) {
                    data.setBuyertaxid("IT");
                }
            }
        }
    }

    /**
     * 添加形式转的买卖记录
     */
    private List<B2bDataDTO> addProFormaMm(String start, String end, List<B2bDataDTO> mainData) {
        List<B2bDataDTO> result = new ArrayList<>();

        List<B2bDataDTO> proForMaMmList = proForMaMmMapper.getProForMaMm(start, end);

        // 创建一个以sheetnumber为键的映射，存储mainData中的buyer和buyertaxid
        Map<String, B2bDataDTO> mainDataMap = mainData.stream().filter(data -> data.getSheetnumber() != null).collect(Collectors.toMap(B2bDataDTO::getSheetnumber, data -> data, (existing, replacement) -> existing // 处理重复键，保留第一个
        ));

        // 为proForMaMmList中的每条记录设置buyer和buyertaxid
        for (B2bDataDTO proFormaRecord : proForMaMmList) {
            String sheetnumber = proFormaRecord.getSheetnumber();
            if (sheetnumber != null && mainDataMap.containsKey(sheetnumber)) {
                B2bDataDTO mainRecord = mainDataMap.get(sheetnumber);
                proFormaRecord.setBuyer(mainRecord.getBuyer());
                proFormaRecord.setBuyertaxid(mainRecord.getBuyertaxid());
                proFormaRecord.setFromcountry(proFormaRecord.getBuyertaxid() != null ? proFormaRecord.getBuyertaxid() : "");

                // 设置seller为getBuyer(buyer, buyertaxid)的结果
                String seller = getBuyer(proFormaRecord.getBuyer(), proFormaRecord.getBuyertaxid());
                proFormaRecord.setSeller(seller);

                // 在Java中，我们不需要实际删除字段，只需要将它们设为null
                proFormaRecord.setBuyer(null);
                proFormaRecord.setBuyertaxid(null);

                // 在Java中，我们将buyermm字段的值复制到buyer字段
                proFormaRecord.setBuyer(proFormaRecord.getBuyermm());
                // 将buyermm设为null，因为它已经被重命名为buyer
                proFormaRecord.setBuyermm(null);

                if (shouldIncludeProFormaRecord(proFormaRecord)) {
                    // 在Java中，我们将这些字段设为null
                    proFormaRecord.setMmTocountry(null);
                    proFormaRecord.setXsBelongs(null);

                    result.add(proFormaRecord);
                }
            }
        }

        return result;
    }

    /**
     * 处理买家逻辑
     */
    private String getBuyer(String tocompany, String buyertaxid) {
        // 针对fds、costway,拼接的国家为买方国家
        String tocountry = (buyertaxid != null) ? buyertaxid.toLowerCase() : "";

        if ("fds".equals(tocompany)) {
            return "fds-" + tocountry;
        } else if ("costway".equals(tocompany)) {
            return "costway-" + tocountry;
        } else {
            return tocompany;
        }
    }

    /**
     * 添加价格
     */
    private List<B2bDataDTO> addPrice(List<B2bDataDTO> hisPrice, List<B2bDataDTO> lastPrice, List<B2bDataDTO> firstDay) {
        // 构建历史价格映射，按sort字段排序并按cpbh分组，取每组第一条记录
        Map<String, List<B2bDataDTO>> withHisPriceMap = hisPrice.stream().sorted(Comparator.comparing(B2bDataDTO::getSort)) // 按sort字段升序排序
                .collect(Collectors.groupingBy(B2bDataDTO::getCpbh));// 按cpbh分组，保留第一个（排序后的第一个）

        //设置得到日期的第一个数据并设置参数
        List<B2bDataDTO> withHisPrice = getFirstData(withHisPriceMap).stream().peek(f -> {
            f.setPrice(f.getHisPrice());
            f.setOceanfee(f.getHisOceanfee());
        }).collect(Collectors.toList());

        //得到不重复的cpbh数据
        List<B2bDataDTO> withoutPriceData = mergeAndGetDoNotRepeatCpbh(firstDay, withHisPrice);

        Map<String, List<B2bDataDTO>> lastPriceMap = lastPrice.stream().collect(Collectors.groupingBy(B2bDataDTO::getCpbh));
        //merge -->  mainData数据和plnPriceData数据
        List<B2bDataDTO> addLastPrice = new ArrayList<>();
        for (B2bDataDTO mainItem : withoutPriceData) {
            String key = mainItem.getCpbh();
            if (lastPriceMap.containsKey(key)) {
                List<B2bDataDTO> B2bDataDTOS = lastPriceMap.get(key);
                B2bDataDTOS.forEach(f -> {
                    B2bDataDTO newItem = new B2bDataDTO();
                    BeanUtils.copyProperties(mainItem, newItem);
                    newItem.setLastPrice(f.getLastPrice());
                    newItem.setLastOceanfee(f.getLastOceanfee());
                    addLastPrice.add(newItem);
                });
            } else {
                addLastPrice.add(mainItem);
            }
        }
        addLastPrice.forEach(f -> {
            f.setPrice(f.getLastPrice());
            f.setOceanfee(f.getLastOceanfee());
        });

        return Stream.concat(withHisPrice.stream(), addLastPrice.stream())
                .collect(Collectors.toList());
    }

    private List<B2bDataDTO> getFirstData(Map<String, List<B2bDataDTO>> FirstDataMap) {
        // 取每组第一条记录
        Map<String, B2bDataDTO> first_day = new HashMap<>();
        for (String key : FirstDataMap.keySet()) {
            List<B2bDataDTO> group = FirstDataMap.get(key);
            if (!first_day.containsKey(key) && !group.isEmpty()) {
                first_day.put(key, group.get(0));
            }
        }

        return new ArrayList<>(first_day.values());
    }
    
    // 合并并获取不重复的cpbh数据
    private static List<B2bDataDTO> mergeAndGetDoNotRepeatCpbh(List<B2bDataDTO> firstDay, List<B2bDataDTO> withHisPrice) {
        // 1. 合并 withHisPrice 和 firstDay 两个集合
        List<B2bDataDTO> combined = Stream.concat(withHisPrice.stream(), firstDay.stream())
                .collect(Collectors.toList());

        // 2. 统计每个 cpbh 在合并后的总出现次数
        Map<String, Long> cpbhCount = combined.stream()
                .map(B2bDataDTO::getCpbh)
                .collect(Collectors.groupingBy(
                        cpbh -> cpbh,  // 按 cpbh 分组
                        Collectors.counting()  // 统计每个分组的数量
                ));

        // 3. 筛选出仅出现一次的 cpbh 对应的记录（即两个集合中均不重复的记录）
        return combined.stream()
                .filter(dto -> cpbhCount.get(dto.getCpbh()) == 1)  // 只保留出现次数为1的记录
                .collect(Collectors.toList());
    }

    /**
     * 添加ID
     */
    private List<B2bDataDTO> addId(List<B2bDataDTO> data, String date) {
        List<B2bDataDTO> idData = data.stream()
                .map(item -> {
                    B2bDataDTO newItem = new B2bDataDTO();
                    BeanUtils.copyProperties(item, newItem);
                    return newItem;
                })
                .collect(Collectors.toList());

        // 区分转运和非转运数据，相当于Python中的loc筛选
        List<B2bDataDTO> proFormaData = idData.stream()
                .filter(item -> "转运".equals(item.getType()))
                .map(item -> {
                    // 为转运数据创建副本
                    B2bDataDTO newItem = new B2bDataDTO();
                    BeanUtils.copyProperties(item, newItem);
                    return newItem;
                })
                .collect(Collectors.toList());

        idData = idData.stream()
                .filter(item -> !"转运".equals(item.getType()))
                .collect(Collectors.toList());

        List<B2bDataDTO> result = new ArrayList<>();

        // 处理转运数据
        for (B2bDataDTO item : proFormaData) {
            // 对买卖转销售记录增加inoutDate区分，确保发票id唯一性
            item.set_idString(date + item.getDate() + item.getSeller() + item.getBuyer() + item.getFromcountry() + item.getSellertaxid() + item.getBuyertaxid());
            calculateAndSetId(item);
            result.add(item);
        }

        // 处理非转运数据
        for (B2bDataDTO item : idData) {
            item.set_idString(date + item.getSeller() + item.getBuyer() + item.getFromcountry() + item.getSellertaxid() + item.getBuyertaxid());
            calculateAndSetId(item);
            result.add(item);
        }

        return result;
    }

    /**
     * 计算并设置ID
     */
    private void calculateAndSetId(B2bDataDTO item) {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] hashBytes = md.digest(item.get_idString().getBytes(StandardCharsets.UTF_8));
            StringBuilder sb = new StringBuilder();
            for (byte b : hashBytes) {
                sb.append(String.format("%02x", b));
            }
            item.set_id(sb.toString());
        } catch (NoSuchAlgorithmException e) {
            log.error("计算MD5哈希失败", e);
        }
    }

    /**
     * 添加方向
     */
    private List<B2bDataDTO> addDirection(List<B2bDataDTO> data) {
        List<B2bDataDTO> result = new ArrayList<>();

        // 添加进口数据
        for (B2bDataDTO item : data) {
            B2bDataDTO inItem = new B2bDataDTO();
            BeanUtil.copyProperties(item, inItem);
            inItem.setBelongs(item.getBuyer());
            inItem.setDirection("in");
            result.add(inItem);
        }

        // 添加出口数据
        for (B2bDataDTO item : data) {
            B2bDataDTO outItem = new B2bDataDTO();
            BeanUtil.copyProperties(item, outItem);
            outItem.setBelongs(item.getSeller());
            outItem.setDirection("out");
            result.add(outItem);
        }

        return result;
    }

    /**
     * 添加发票日期
     */
    private List<B2bDataDTO> addInvoiceDate(List<B2bDataDTO> data, String end) {
        List<B2bDataDTO> result = new ArrayList<>();

        // 获取中国公司列表
        List<String> chinaCorpList = metaCorpHeaderMapper.selectChinaCorpList();

        // 计算两个日期
        LocalDate nextFirst;
        LocalDate currLast;
        try {
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
            nextFirst = LocalDate.parse(end, formatter);
            currLast = nextFirst.minusDays(1);
        } catch (Exception e) {
            log.error("解析日期失败", e);
            return result;
        }

        for (B2bDataDTO item : data) {

            // 根据是否为中国公司设置不同的发票日期
            try {
                String tocompany = item.getBuyer();
                boolean isChinaCorp = false;

                if (tocompany != null && !tocompany.isEmpty()) {
                    // 提取tocompany中"-"前的部分
                    String tocompanyPrefix = tocompany.split("-")[0];
                    // 判断是否在中国公司列表中
                    isChinaCorp = chinaCorpList.contains(tocompanyPrefix);
                }

                // 如果是到中国公司的，使用nextFirst日期，否则使用currLast日期
                LocalDate invoiceDate = isChinaCorp ? nextFirst : currLast;
                item.setInvoicedate(java.sql.Date.valueOf(invoiceDate));
            } catch (Exception e) {
                log.error("设置发票日期失败", e);
            }

            result.add(item);
        }

        log.info("添加发票日期成功，数据条数：{}", result.size());

        return result;
    }

    /**
     * 添加出口价格
     */
    private Map<String, Object> addExportPrice(List<B2bDataDTO> mainData, String priceDate) {
        Map<String, Object> result = new HashMap<>();

        try {
            List<B2bDataDTO> exportPriceData = metaStkCustomsMapper.selectList();
            // 左连接mainData和exportPriceData（基于cpbh和abbrbelongs/pricebelongs）

            // 创建一个映射，键为cpbh+pricebelongs，值为匹配的exportPrice记录列表
            Map<String, List<B2bDataDTO>> exportPriceDataMap = exportPriceData.stream().collect(Collectors.groupingBy(f -> f.getCpbh() + f.getBelongs()));

            // 执行类似pandas merge的左连接操作
            List<B2bDataDTO> mergeData = new ArrayList<>();
            for (B2bDataDTO mainItem : mainData) {
                String key = mainItem.getCpbh() + mainItem.getAbbrbelongs();
                leftMergeData(mainItem, exportPriceDataMap, key, mergeData);
            }

            // 分离有出口价格和无出口价格的数据
            Map<String, B2bDataDTO> WithExportPriceData = dealMergeData(priceDate, mergeData);

            List<B2bDataDTO> withoutExportPriceData = mainData.stream().filter(item -> !WithExportPriceData.containsKey(item.getCpbh() + item.getSheetnumber() + item.getDirection())).collect(Collectors.toList());

            result.put("withExportPriceData", new ArrayList<>(WithExportPriceData.values()));
            result.put("withoutExportPriceData", withoutExportPriceData);

            log.info("添加出口价格成功，有出口价格数据条数：{}，无出口价格数据条数：{}", WithExportPriceData.size(), withoutExportPriceData.size());

            return result;
        } catch (Exception e) {
            log.error("添加出口价格失败", e);
            throw new RuntimeException("添加出口价格失败", e);
        }
    }

    /**
     * 添加异常出口价格
     */
    private List<B2bDataDTO> addAbnormalExportPrice(List<B2bDataDTO> nopriceData, String priceDate) {
        try {
            // 查询出口价格数据
            List<B2bDataDTO> exportPriceData = metaStkCustomsMapper.selectList();

            // 创建一个映射，键为cpbh+pricebelongs，值为匹配的exportPrice记录列表
            Map<String, List<B2bDataDTO>> exportPriceDataMap = exportPriceData.stream().collect(Collectors.groupingBy(B2bDataDTO::getCpbh));

            // 执行类似pandas merge的左连接操作
            List<B2bDataDTO> mergeData = new ArrayList<>();
            for (B2bDataDTO mainItem : nopriceData) {
                String key = mainItem.getCpbh();
                leftMergeData(mainItem, exportPriceDataMap, key, mergeData);
            }

            //处理后续的mergeData数据
            Map<String, B2bDataDTO> WithExportPriceData = dealMergeData(priceDate, mergeData);

            log.info("添加异常出口价格成功，数据条数：{}", WithExportPriceData.values().size());

            return new ArrayList<>(WithExportPriceData.values());

        } catch (Exception e) {
            log.error("添加异常出口价格失败", e);
            throw new RuntimeException("添加异常出口价格失败", e);
        }
    }

    /**
     * 左连接处理数据
     */
    private static void leftMergeData(B2bDataDTO mainItem, Map<String, List<B2bDataDTO>> exportPriceDataMap, String key, List<B2bDataDTO> mergeData) {
        if (exportPriceDataMap.containsKey(key)) {
            // 对于每个匹配的exportPrice记录，都创建一条新记录（模拟pandas merge的笛卡尔积效果）
            for (B2bDataDTO exportPriceItem : exportPriceDataMap.get(key)) {
                B2bDataDTO mergedItem = new B2bDataDTO();
                BeanUtil.copyProperties(mainItem, mergedItem);
                mergedItem.setExportprice(exportPriceItem.getExportprice());
                mergedItem.setExportpricedate(exportPriceItem.getExportpricedate());
                mergeData.add(mergedItem);
            }
        } else {
            mergeData.add(mainItem);
        }
    }

    /**
     * 处理合并后的数据
     */
    private static Map<String, B2bDataDTO> dealMergeData(String priceDate, List<B2bDataDTO> mergeData) {
        // 分离有出口价格和无出口价格的数据
        List<B2bDataDTO> withExportPriceData = mergeData.stream().filter(item -> item.getExportprice() != null).collect(Collectors.toList());

        // 计算日期差并过滤
        LocalDate priceLocalDate = LocalDate.parse(priceDate);
        List<B2bDataDTO> withValidDateDiff = new ArrayList<>();
        // date_differ>0的数据
        for (B2bDataDTO item : withExportPriceData) {
            if (item.getExportpricedate() != null) {
                try {
                    // 正确地将Date转换为LocalDate
                    LocalDate exportPriceDate = item.getExportpricedate().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
                    long dateDiff = ChronoUnit.DAYS.between(exportPriceDate, priceLocalDate);

                    // 排除endDate后的数据（date_differ > 0）
                    if (dateDiff > 0) {
                        item.setDateDiffer(dateDiff); // 使用dateDiffer字段存储日期差
                        withValidDateDiff.add(item);
                    }
                } catch (Exception e) {
                    log.warn("日期解析失败: {}", item.getExportpricedate());
                }
            }
        }

        // 按照日期差、数量、出口价格排序，然后按cpbh和index(sheetNumber+direction)分组，取每组第一条记录
        Map<String, List<B2bDataDTO>> groupedData = withValidDateDiff.stream().sorted(Comparator.comparing(B2bDataDTO::getDateDiffer).thenComparing(B2bDataDTO::getSl, Comparator.nullsLast(Comparator.reverseOrder())).thenComparing(B2bDataDTO::getExportprice, Comparator.nullsLast(Comparator.reverseOrder()))).collect(Collectors.groupingBy(f -> f.getCpbh() + f.getSheetnumber() + f.getDirection()));

        // 取每组第一条记录
        Map<String, B2bDataDTO> WithExportPriceData = new HashMap<>();
        for (String key : groupedData.keySet()) {
            List<B2bDataDTO> group = groupedData.get(key);
            if (!WithExportPriceData.containsKey(key) && !group.isEmpty()) {
                WithExportPriceData.put(key, group.get(0));
            }
        }
        return WithExportPriceData;
    }

    /**
     * 判断proForma记录是否应该包含在结果中
     * 对应Python中的query筛选逻辑
     */
    private boolean shouldIncludeProFormaRecord(B2bDataDTO record) {
        String seller = record.getSeller();
        String xsBelongs = record.getXsBelongs();
        String fromCountry = record.getFromcountry();
        String mmToCountry = record.getMmTocountry();

        // 检查seller是否以'costway'或'fds'开头
        boolean sellerStartsWithCostwayOrFds = (seller != null) && (seller.startsWith("costway") || seller.startsWith("fds"));

        // 检查xsBelongs是否以'costway'或'fds'开头
        boolean xsBelongsStartsWithCostwayOrFds = (xsBelongs != null) && (xsBelongs.startsWith("costway") || xsBelongs.startsWith("fds"));

        // 前两个条件必须同时满足
        boolean firstCondition = sellerStartsWithCostwayOrFds && xsBelongsStartsWithCostwayOrFds;

        if (!firstCondition) {
            return false;
        }

        // 检查fromcountry != mmTocountry
        boolean countriesNotEqual = !Objects.equals(fromCountry, mmToCountry);

        if (countriesNotEqual) {
            return true;
        }

        // 如果fromcountry == mmTocountry，则需要满足额外条件
        // seller != xsBelongs
        boolean sellerNotEqualsXsBelongs = !Objects.equals(seller, xsBelongs);

        if (!sellerNotEqualsXsBelongs) {
            return false;
        }

        // ~(seller.str.startswith('fds') and xs_belongs.str.startswith('fds'))
        // 即seller和xs_belongs不能都以'fds'开头
        boolean bothStartWithFds = seller.startsWith("fds") && xsBelongs.startsWith("fds");

        return !bothStartWithFds;
    }
}